package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

// 1.函数定义
func eval(a, b int, op string) (int, error) {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		// 如果有多个返回值，不用的话可以用 _ 标记
		q, _ := div(a, b)
		return q, nil
	default:
		return 0, fmt.Errorf("unsupported operation: %s", op)
	}
}

// 2.返回多个值的函数
func div(a, b int) (q, r int) {
	return a / b, a % b
}

func div1(a, b int) (q, r int) {
	q = a / b
	r = a % b
	return
}

// 3 函数式编程，函数的参数也可以是一个函数
func apply(op func(int, int) int, a, b int) int {
	p := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("Calling function %s with args (%d, %d)\n", opName, a, b)
	return op(a, b)
}

func pow(a, b int) int {
	return int(math.Pow(float64(a), float64(b)))
}

// 可变参数
func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	return s
}

// 交换两个数的值
func swap(a, b *int) {
	*a, *b = *b, *a
}

func swapVale(a, b int) (int, int) {
	return b, a
}

func main() {
	fmt.Println(eval(3, 4, "/"))
	fmt.Println(div(13, 3))
	div1(13, 3)

	if result, err := eval(3, 4, "x"); err != nil {
		fmt.Println("Error: ", err)
	} else {
		fmt.Println(result)
	}
	// 方法传递
	fmt.Println(apply(pow, 3, 4))

	// 匿名函数
	fmt.Println(apply(func(a int, b int) int {
		return int(math.Pow(float64(a), float64(b)))
	}, 3, 4))

	fmt.Println(sum(1, 2, 3, 4, 5))

	a, b := 3, 4
	fmt.Println(swapVale(a, b))
	swap(&a, &b)
	fmt.Println(a, b)

}
